/**
 * @Auther: ChenforCode
 * @Date: 2018/9/11 13:47
 * @Description:
 */
package cn.chenforcode.dao;

import cn.chenforcode.entity.Book;
import oracle.jdbc.OracleType;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.procedure.ProcedureCall;
import org.hibernate.query.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate5.SessionFactoryUtils;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.ParameterMode;
import java.sql.CallableStatement;
import java.sql.SQLException;
import java.sql.Types;
import java.util.List;

@Repository
@Transactional
public class BookDAO {

    @Autowired
    private SessionFactory sessionFactory;

    public Session getSession() {
        return sessionFactory.getCurrentSession();
    }

    /**
     * @return void
     * @Author ChenforCode
     * @Description //TODO 向数据库中插入一条新书
     * @Date 20:54 2018/9/11
     * @Param [book]
     **/
    public void addBook(Book book) {
        this.getSession().save(book);
    }

    /**
     * @return int
     * @Author ChenforCode
     * @Description //TODO 判断是否可以加书
     * @Date 20:55 2018/9/11
     * @Param [bno]
     **/
    public int queryCanAdd(String bno) {
        CallableStatement statement = null;
        int retValue = 0;
        try {
            statement = SessionFactoryUtils.getDataSource(sessionFactory)
                    .getConnection().prepareCall("{call querybkcanadd(?,?)}");
            statement.setString(1, bno);
            statement.registerOutParameter(2, OracleType.NUMBER);
            statement.execute();

            retValue = statement.getInt(2);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            return retValue;
        }
    }

    /**
     * @return void
     * @Author ChenforCode
     * @Description //TODO 根据书号删除书籍
     * @Date 20:58 2018/9/11
     * @Param [bno]
     **/
    public void deleteBookByBno(String bno) {
        this.getSession().createQuery("delete from Book where bno = ?1")
                .setParameter(1, bno).executeUpdate();
    }

    /**
     * @return int
     * @Author ChenforCode
     * @Description //TODO 判断是否可以删除书籍
     * @Date 21:38 2018/9/11
     * @Param [bno]
     **/
    public int queryCanDelete(String bno) {
        CallableStatement statement = null;
        int retValue = 0;
        try {
            statement = SessionFactoryUtils.getDataSource(sessionFactory)
                    .getConnection().prepareCall("{call querybkcandel(?,?)}");
            statement.setString(1, bno);
            statement.registerOutParameter(2, OracleType.NUMBER);
            statement.execute();

            retValue = statement.getInt(2);
        } catch (SQLException
                e) {
            e.printStackTrace();
        } finally {
            return retValue;
        }
    }

    /**
     * @return void
     * @Author ChenforCode
     * @Description //TODO 更新书籍
     * @Date 21:40 2018/9/11
     * @Param [book]
     **/
    public void updateBook(Book book) {
        this.getSession().update(book);
    }

    /**
     * @return java.util.List<cn.chenforcode.entity.Book>
     * @Author ChenforCode
     * @Description //TODO 查询所有的书籍
     * @Date 21:42 2018/9/11
     * @Param []
     **/
    public List<Book> getAllBooks() {
        return this.getSession().createQuery("from Book").list();
    }

    /**
     * @return cn.chenforcode.entity.Book
     * @Author ChenforCode
     * @Description //TODO 根据书号查询书籍
     * @Date 21:44 2018/9/11
     * @Param [bno]
     **/
    public Book getBookByBno(String bno) {
        return (Book) this.getSession().createQuery("from Book where bno = ?1")
                .setParameter(1, bno).uniqueResult();
    }

}
